using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Windows.Input;
using CodeGears.WorkItemTracking.ChartingDashboard.Domain;
using Visifire.Charts;

namespace CodeGears.WorkItemTracking.ChartingDashboard
{
    public class ChartViewModel : ViewModeBase
    {
        private readonly IWorkItemsService _workItemsService;
        private QueryResult _queryResult;
        
        #region Commands

        private ICommand _updateChartCommand;
        public ICommand UpdateChartCommand
        {
            get
            {
                if(_updateChartCommand == null)
                {
                    _updateChartCommand = new DelegateCommand(() =>
                                                                  {
                                                                      RunQuery();
                                                                      DisplayChart();
                                                                  });
            }
                return _updateChartCommand;
            }
        }
        #endregion

        #region Properties

        public ObservableCollection<Project> Projects { get; private set; }
        public ObservableCollection<Query> Queries { get; private set; }
        public ObservableCollection<Field> Fields { get; private set; }
        public DataSeries Series { get; set; }

        private Project _selectedProject;
        public Project SelectedProject
        {
            get { return _selectedProject; }
            set
            {
                _selectedProject = value;
                OnPropertyChanged("SelectedProject");
                RetrieveQueries();
            }
        }

        private Field _selectedField;
        public Field SelectedField
        {
            get { return _selectedField; }
            set
            {
                _selectedField = value;
                OnPropertyChanged("SelectedField");
                DisplayChart();
            }
        }

        private string _selectedChartType = "Column";
        public string SelectedChartType
        {
            get { return _selectedChartType; }
            set
            {
                _selectedChartType = value;
                OnPropertyChanged("SelectedChartType");
                UpdateChartType();
            }
        }

        public RenderAs RenderChartAs
        {
            get { return (RenderAs) Enum.Parse(typeof (RenderAs), SelectedChartType); }
        }

        private Query _selectedQuery;
        public Query SelectedQuery
        {
            get { return _selectedQuery; }
            set
            {
                _selectedQuery = value;
                OnPropertyChanged("SelectedQuery");
                RunQuery();
                RetrieveFields();
            }
        }

        public List<string> ChartTypes
        {
            get { return new List<string>(Enum.GetNames(typeof (RenderAs))); }
        }
        #endregion

        public ChartViewModel(IServiceProvider server)
        {
            _workItemsService = new WorkItemsService(server.GetService(typeof(Microsoft.TeamFoundation.WorkItemTracking.Client.WorkItemStore)) as Microsoft.TeamFoundation.WorkItemTracking.Client.WorkItemStore);
            Projects = new ObservableCollection<Project>();
            Queries = new ObservableCollection<Query>();
            Fields = new ObservableCollection<Field>();
            Series = new DataSeries();
        }

        public void LoadProjects()
        {
            Projects.Clear();
            Projects.AddRange(this._workItemsService.GetProjects());
        }

        private void RunQuery()
        {
            _queryResult = this._workItemsService.RunQuery(SelectedQuery, SelectedProject);
        }

        private void RetrieveQueries()
        {
            Queries.Clear();

            if (SelectedProject == null) return;

            Queries.AddRange(SelectedProject.GetQueries());
        }

        private void RetrieveFields()
        {
            Fields.Clear();

            if (_queryResult == null) return;

            Fields.AddRange(this._queryResult.GetFieldDefinitions());
        }

        private void DisplayChart()
        {
            if (_queryResult == null) return;

            Series.DataPoints.Clear();
            Series.RenderAs = RenderChartAs;

            var map = new Dictionary<object, int>();

            foreach (Microsoft.TeamFoundation.WorkItemTracking.Client.WorkItem workItem in _queryResult)
            {
                var value = workItem[SelectedField.TfsField.Name];

                if (SelectedField.TfsField.Name.Contains("Date"))
                {
                    var dateTime = DateTime.Parse(value.ToString());
                    value = dateTime.Date.ToShortDateString();
                }

                if (map.ContainsKey(value) == false)
                {
                    map.Add(value, 1);
                }
                else
                {
                    map[value]++;
                }
            }

            foreach (var pair in map)
            {
                var dataPoint = new DataPoint {YValue = pair.Value, AxisXLabel = pair.Key.ToString()};
                Series.DataPoints.Add(dataPoint);
            }
        }

        private void UpdateChartType()
        {
            if(Series == null) return;

            Series.RenderAs = RenderChartAs;
        }
    }
}